package com.daoshu.mds.message.config;

import com.daoshu.mds.message.service.IPersonGroupService;
import lombok.extern.log4j.Log4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration;
import org.springframework.web.socket.handler.WebSocketHandlerDecorator;
import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory;

import javax.annotation.Resource;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

//import com.daoshu.mds.logoperate.service.ILoginLogService;

/**
 * socket核心配置容器
 */
@Configuration
@EnableWebSocketMessageBroker
@Log4j
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

	@Autowired
	private SessionHandShakeInterceptor sessionHandShakeInterceptor;
	
	@SuppressWarnings("unused")
	@Autowired
	private IPersonGroupService personGroupService;
	
//	@Autowired
//	private ILoginLogService loginLogService;
	@Autowired
	private ScheduledThreadPoolExecutor schedul;
	@Resource
	private RedisTemplate<String,String> redisTemplate;
	@Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/microGroupMessage", "/alarmMessage", "/notice");
        config.setApplicationDestinationPrefixes("/microGroupMessage", "/alarmMessage", "/notice");
    }

	@Override
	public void registerStompEndpoints(StompEndpointRegistry registry) {
		registry.addEndpoint("/msg-websocket").setAllowedOrigins("*").addInterceptors(sessionHandShakeInterceptor).withSockJS(); // web端消息地址
		registry.addEndpoint("/apk-websocket").addInterceptors(sessionHandShakeInterceptor); // apk端接收消息地址
	}
	
	@Override
	public void configureWebSocketTransport(final WebSocketTransportRegistration registration) {
	    registration.addDecoratorFactory(new WebSocketHandlerDecoratorFactory() {
	      @Override
	      public WebSocketHandler decorate(final WebSocketHandler handler) {
	        return new WebSocketHandlerDecorator(handler) {
	          @Override
	          public void afterConnectionEstablished(final WebSocketSession session) throws Exception {
	            // 客户端与服务器端建立连接后，此处记录谁上线了
	            String personId = session.getAttributes().get("personId").toString();
	            log.info("online: " + personId);
	            redisTemplate.opsForSet().add("socketSessions", personId);
	            super.afterConnectionEstablished(session);
	          }

	          @Override
	          public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
	            // 客户端与服务器端断开连接后，此处记录谁下线了
	            String personId = session.getAttributes().get("personId").toString();
	            redisTemplate.opsForSet().remove("socketSessions", personId);
	            log.error("offline: " + personId);
	            schedul.schedule(() -> closedConnectionOperation(personId), 1, TimeUnit.MINUTES);
	            // personGroupService.updateReadTimeOffline(personId);
	            super.afterConnectionClosed(session, closeStatus);
	          }
	        };
	      }
	    });
	    super.configureWebSocketTransport(registration);
	}
	
	private void closedConnectionOperation(String personId) {
		if(StringUtils.isEmpty(personId))
			return;
		Boolean flag = redisTemplate.opsForSet().isMember("socketSessions", personId);
		if(!flag) {
			log.error("下线操作: " + personId);
//			loginLogService.updateLoginoutTime(personId);
		}else {
			log.error(personId + "用户还在线，不操作任何数据!");
		}
	}
}
